package pkg.nudroid.translator;

import java.util.HashMap;
import java.util.HashSet;

public class SymbolTable 
{
	private static HashMap<String,STValue> symbolTable;
	private static HashSet<String> initializedVariables;
	private static HashSet<String> initializedInputs;
	private static int temp;
	
	public static enum Type
	{
		APP,
		PAGE,
		TEXT,
		INPUT,
		LINK,
		IMAGE,
		LIST,
		TABLE,
		AUDIO,
		VIDEO,
		BUTTON,
		FUNCTION,
		VARIABLE
	}
	
	
	
	public static class STValue
	{
		Type type;
		int value;
		
		public STValue(Type t)
		{
			type = t;
		}
		
		public STValue(int d)
		{
			type = Type.VARIABLE;
			value = d;
		}
		
		public double getValue()
		{
			if(type == Type.VARIABLE)
				return value;
			else if(type == Type.INPUT)
			{
				throw new IllegalArgumentException("Input objects not yet supported.");
			}
			else
			{
				throw new IllegalArgumentException("Not a variable name.");
			}
			
			//TODO - input objects? Not sure how to do this atm.
		}
	}
	
	static
	{
		initialize();
	}
	
	public static void initialize()
	{
		symbolTable = new HashMap<String, STValue>();
		initializedVariables = new HashSet<String>();
		initializedInputs = new HashSet<String>();
		temp = 0;
		Init.init();
	}
	
	public static String tempVarName()
	{
		String name = "temporaryVariableName" + temp;
		temp++;
		return name;
	}
	
	public static boolean addSymbol(String id, Type t)
	{
		if (symbolTable.containsKey(id))
			return false;
			
		symbolTable.put(id,new STValue(t));
		return true;
	}
	
	public static boolean addVar(String id, int d)
	{
		if(symbolTable.containsKey(id))
			return false;
		
		symbolTable.put(id, new STValue(d));
		return true;
	}

	public static boolean contains(String id)
	{
		return symbolTable.containsKey(id);
	}

	public static Type typeOfID(String id)
	{
		return symbolTable.get(id).type;
	}
	
	public static int getVar(String id)
	{
		return symbolTable.get(id).value;
	}
	
	public static void setVar(String id, int d)
	{
		symbolTable.get(id).value = d;
	}
	
	public static boolean containsVariable(String id)
	{
		return initializedVariables.contains(id);
	}
	
	public static void initializeVariable(String id)
	{
		if(containsInput(id))
			System.err.println(id + " has already been declared as an input.");
		
		initializedVariables.add(id);
	}
	
	public static void clearInputs()
	{
		initializedInputs = new HashSet<String>();
	}
	
	public static boolean containsInput(String id)
	{
		return initializedInputs.contains(id);
	}
	
	public static void initializeInput(String id)
	{
		if(containsVariable(id))
		{
			System.err.println(id + " has already been declared as a variable.");
			return;
		}
		initializedInputs.add(id);
	}
	
	/*
  	Parses s as an integer.
  	If s is not an integer, then it returns 0
  */
  static int safeParseInt(String s)
  {
  	try
  	{
  		int i = Integer.parseInt(s);
  		return i;
  	}
  	catch(NumberFormatException e)
  	{
  		return 0;
  	}
  }
	
}
